{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {},
   "outputs": [
    {
     "ename": "SyntaxError",
     "evalue": "invalid syntax (<ipython-input-57-22c1372ac43e>, line 1)",
     "output_type": "error",
     "traceback": [
      "\u001b[0;36m  File \u001b[0;32m\"<ipython-input-57-22c1372ac43e>\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m    https://grouplens.org/datasets/movielens/1m/\u001b[0m\n\u001b[0m           ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n"
     ]
    }
   ],
   "source": [
    "https://grouplens.org/datasets/movielens/1m/"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "import math\n",
    "import sys\n",
    "import pandas\n",
    "import numpy as np\n",
    "from collections import defaultdict\n",
    "from operator import itemgetter\n",
    "from tqdm import tqdm\n",
    "import pandas as pd\n",
    "\n",
    "def createDict(rates):\n",
    "    user_dict = {}\n",
    "    movie_dict = {}\n",
    "    for i in rates:\n",
    "        if i[0] in user_dict:\n",
    "            user_dict[i[0]].append((i[1], i[2]))\n",
    "        else:\n",
    "            user_dict[i[0]] = [(i[1], i[2])]\n",
    "        if i[1] in movie_dict:\n",
    "            movie_dict[i[1]].append(i[0])\n",
    "        else:\n",
    "            movie_dict[i[1]] = [i[0]]\n",
    "    user_txt=pd.Series(user_dict)\n",
    "    #user_txt.to_csv('user_txt.csv')\n",
    "    item_txt = pd.Series(movie_dict)\n",
    "    #item_txt.to_csv('job_txt.csv')\n",
    "    return user_dict, movie_dict\n",
    "\n",
    "\n",
    "def itemCF(user_dict):\n",
    "    N = dict()\n",
    "    C = defaultdict(defaultdict)\n",
    "    W = defaultdict(defaultdict)\n",
    "    for key in tqdm(user_dict):\n",
    "        for i in user_dict[key]:\n",
    "            if i[0] not in N.keys():  \n",
    "                N[i[0]] = 0\n",
    "            N[i[0]] += 1  \n",
    "            for j in user_dict[key]:\n",
    "                if i[0] == j[0]:\n",
    "                    continue\n",
    "                if j[0] not in C[i[0]].keys():\n",
    "                    C[i[0]][j[0]] = 0\n",
    "                C[i[0]][j[0]] += 1  \n",
    "    with open('sim_result.csv', 'w') as f:\n",
    "        for i, related_item in tqdm(C.items()):\n",
    "            for j, cij in related_item.items():\n",
    "                W[i][j] = cij / math.sqrt(N[i] * N[j])\n",
    "                data = [str(i),str(j),str(W[i][j]),str(cij),str(N[i]),str(N[j])]\n",
    "                f.write(','.join(data)+'\\n')\n",
    "    return W\n",
    "\n",
    "def recommondation(user_id, user_dict, K, W):\n",
    "    rank = defaultdict(int)\n",
    "    l = list()\n",
    "    for i, score in user_dict[user_id]:\n",
    "        click_list = [i[0] for i in user_dict[user_id]]\n",
    "        for j, wj in sorted(W[i].items(), key=itemgetter(1), reverse=True)[0:K]: \n",
    "            if j in click_list:\n",
    "                continue\n",
    "            rank[j] += score * wj  \n",
    "    l = sorted(rank.items(), key=itemgetter(1), reverse=True)[0:10]\n",
    "    return l\n",
    "\n",
    "if __name__=='__main__':\n",
    "    ratings = pd.read_table('ratings.dat', header=None, names=['UserID', 'MovieID', 'Rating', 'Timestamp'], sep='::')\n",
    "    users = pd.read_table('users.dat', header=None, names=['UserID','Gender','Age','Occupation','Zip-code'], sep='::')\n",
    "    movies = pd.read_table('movies.dat', header=None, names=['MovieID', 'Title', 'Genres'], sep='::')\n",
    "\n",
    "    user_dict, movie_dict = createDict(ratings[['UserID', 'MovieID', 'Rating']].values)\n",
    "    W = itemCF(user_dict)\n",
    "\n",
    "    with open('rec_result.csv','w') as f:\n",
    "        for user_id in user_dict.keys():\n",
    "            l = recommondation(user_id, user_dict, 20, W)\n",
    "            rec_list = ','.join([str(i[0]) for i in l])\n",
    "            f.write(f'{user_id}\\t{rec_list}\\n')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import redis\n",
    "\n",
    "pool = redis.ConnectionPool(host='localhost', port=6379, decode_responses=True)\n",
    "r = redis.Redis(connection_pool=pool)\n",
    "\n",
    "path = './rec_result.csv'\n",
    "\n",
    "cnt = 0\n",
    "with open(path,'r') as f:\n",
    "    for line in f:\n",
    "        uid, movies = line.strip().split('\\t')\n",
    "        r.set(uid, movies)\n",
    "        cnt += 1\n",
    "        if cnt % 1000 == 0:\n",
    "            print(cnt, ' finish')"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.2"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
